ci: configure super-linter with SHA pinning and linter configs#95
ci: configure super-linter with SHA pinning and linter configs#95
Conversation
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
3e44716 to
50b78b0
Compare
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new GitHub Actions "Lint" workflow and local linting/docs configs; plus widespread formatting and documentation edits across workflows, docs, instructions, and small perf-script argument-forwarding changes. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant GH as "GitHub Actions Runner"
participant Repo as "Repository (checkout)"
participant Linter as "github/super-linter"
Dev->>GH: Push / Open PR
GH->>Repo: actions/checkout (fetch-depth: 0)
GH->>Linter: invoke super-linter (env: GITHUB_TOKEN, DEFAULT_BRANCH, VALIDATE_*, EXCLUDE_REGEX)
Linter->>Repo: scan files (YAML, Markdown, JSON, Bash)
Linter-->>GH: return results (exit code, annotations)
GH-->>Dev: CI status and annotations
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
|
Code Climate has analyzed commit 7b167e7 and detected 14 issues on this pull request. Here's the issue category breakdown:
View more on Code Climate. |
There was a problem hiding this comment.
Actionable comments posted: 3
Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Files selected for processing (1)
- .github/workflows/linters.yml (1 hunks)
Additional context used
GitHub Check: Codacy Static Code Analysis
.github/workflows/linters.yml
[warning] 29-29: .github/workflows/linters.yml#L29
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
Additional comments not posted (3)
.github/workflows/linters.yml (3)
7-7: LGTM!The permissions section is correctly defined.
The code changes are approved.
32-32: LGTM!The environment variables section is correctly defined.
The code changes are approved.
15-16: Fix indentation issues.Expected an indentation at 8 instead of at 6.
Apply this diff to fix the indentation issues:
permissions: - contents: read - packages: read + contents: read + packages: readLikely invalid or redundant comment.
7b167e7 to
7eb71c7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
.github/workflows/linters.yml (2)
29-29: Action version should be pinned to a full commit SHASame reasoning as above – avoid running an unexpected future version of Super-linter.
-uses: super-linter/super-linter@v6.6.0 # x-release-please-version +uses: super-linter/super-linter@<full-length-commit-SHA> # v6.6.0
3-6: Indentation &nullkeywords may breakonblock parsingThe jobs don’t start if the workflow’s
onblock is malformed. Lint-bots have already flagged the 2-space indentation and the explicitnullvalues. Replace them with the canonical form and use four-space indentation expected by the repo’s yamllint configuration.-on: # yamllint disable-line rule:truthy - push: null - pull_request: null +on: # yamllint disable-line rule:truthy + push: + pull_request:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/linters.yml(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.{cs,csproj,props,targets} : Run Codacy CLI analysis on all changed files. Fix all reported issues before submitting the PR.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.110Z
Learning: Summarize all changes in the PR description and cite relevant lines from modified files for clarity.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Cite relevant lines from modified files in PR summaries for clarity.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.{cs,csproj,props,targets,md} : All formatting and linting issues flagged by bots or CI must be resolved before requesting review or merging.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.111Z
Learning: Summaries in pull requests should mention key line numbers using the repository citation format.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Summaries in pull requests should mention key line numbers using the repository citation format.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.110Z
Learning: Every pull request must include evidence of running code formatting, building with warnings as errors, and running all unit tests (console log/text or screenshots) in the PR description.
Learnt from: MattKotsenas
PR: rjmurillo/moq.analyzers#325
File: .github/workflows/label-pr.yml:13-13
Timestamp: 2025-01-17T21:45:05.188Z
Learning: As of January 2025, GitHub-hosted ARM64 runners should use the syntax `ubuntu-24.04-arm` in GitHub Actions workflow files, as documented in the GitHub changelog.
Learnt from: MattKotsenas
PR: rjmurillo/moq.analyzers#325
File: .github/workflows/release.yml:24-24
Timestamp: 2025-01-17T21:44:35.686Z
Learning: As of January 2025, GitHub Actions supports ARM64 runners in public repositories (public preview). The runner specification format is `ubuntu-24.04-arm` for ARM64-based Ubuntu runners.
Learnt from: MattKotsenas
PR: rjmurillo/moq.analyzers#325
File: .github/workflows/dependabot-auto-approve.yml:9-9
Timestamp: 2025-01-17T21:43:46.997Z
Learning: As of January 2025, GitHub Actions supports ARM64 runners in public preview. The runner label format is `ubuntu-24.04-arm` for ARM64 Ubuntu runners. This is available for free in public repositories.
Learnt from: MattKotsenas
PR: rjmurillo/moq.analyzers#325
File: .github/workflows/dependabot-auto-approve.yml:9-9
Timestamp: 2025-01-17T21:44:17.410Z
Learning: GitHub Actions now supports ARM64 runners (as of January 2025) with labels like `ubuntu-24.04-arm`. These runners are available for free in public repositories during the public preview period.
Learnt from: MattKotsenas
PR: rjmurillo/moq.analyzers#325
File: .github/workflows/label-issues.yml:14-14
Timestamp: 2025-01-17T21:44:41.600Z
Learning: As of January 2025, GitHub Actions ARM64 runners should use the syntax `ubuntu-24.04-arm` for the `runs-on` field, not the array syntax with separate OS and architecture labels.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.111Z
Learning: When making changes, follow the workflow: Edit/Add Code or Test → Run codacy_cli_analyze → Fix issues if any → Run/Update Tests → Fix test failures if any → Update Docs → Commit & PR.
.github/workflows/linters.yml (9)
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.{cs,csproj,props,targets} : Run Codacy CLI analysis on all changed files. Fix all reported issues before submitting the PR.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.111Z
Learning: When making changes, follow the workflow: Edit/Add Code or Test → Run codacy_cli_analyze → Fix issues if any → Run/Update Tests → Fix test failures if any → Update Docs → Commit & PR.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.{cs,csproj,props,targets,md} : All formatting and linting issues flagged by bots or CI must be resolved before requesting review or merging.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.{csproj,props,targets} : After any dependency change, run Codacy analysis with tool: trivy and resolve vulnerabilities before continuing.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.111Z
Learning: After any dependency change, run Codacy analysis with 'tool: trivy' and resolve vulnerabilities before continuing.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.110Z
Learning: Address all feedback from automated bots (e.g., Codeclimate, formatting/linting bots) as you would human reviewers; resolve all formatting and linting issues flagged by bots or CI before requesting review or merging.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-22T02:59:32.747Z
Learning: Applies to **/*.cs : Run dotnet format and commit all changes. PRs with formatting issues will be rejected.
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-06-25T12:42:47.111Z
Learning: Use Conventional Commits where possible: [optional scope]: .
Learnt from: CR
PR: rjmurillo/moq.analyzers#0
File: .cursor/rules/conventional-commit-messages.mdc:0-0
Timestamp: 2025-06-25T12:42:54.674Z
Learning: The commit type 'feat' must be used when adding a new feature, and 'fix' must be used for bug fixes, aligning with Semantic Versioning (MINOR and PATCH, respectively).
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Codacy Static Code Analysis
- GitHub Check: build (windows-11-arm)
- GitHub Check: build (ubuntu-24.04-arm)
7eb71c7 to
b949e75
Compare
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| C# | Mar 1, 2026 1:29a.m. | Review ↗ |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/linters.yml:
- Around line 24-38: Add the missing Super-linter environment variable to enable
diff-only linting: in the "Super-linter" job where the step uses
super-linter/super-linter@61abc07d755095a68f4987d1c2c3d1d64408f1f9 and the env
block sets GITHUB_TOKEN and validators, add VALIDATE_ALL_CODEBASE: false to that
env list so the runner uses diff-only linting instead of validating the whole
repo.
In `@CONTRIBUTING.md`:
- Around line 362-382: Add an explicit example showing how to run the new
linters CI workflow locally: in the "Local Linting" section add a line
demonstrating the gh act command to invoke .github/workflows/linters.yml (e.g.
gh act -W .github/workflows/linters.yml -j build) so contributors can run the
exact CI job locally before pushing; reference the workflow file name
(.github/workflows/linters.yml) and the section header ("Local Linting") when
adding this single-line example directly above or alongside the existing
Docker/all-linters instructions.
b949e75 to
ef149c8
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Checkout action version comment incorrectly labels SHA
- Updated the actions/checkout SHA from an intermediate v6 commit (34e114876b0b11c390a56381ad16ebd13914f8d5) with incorrect # v4 comment to the canonical v6 release SHA (de0fac2e4500dabe0009e67214ff5f5447ce83dd) with correct # v6 comment, matching other workflows in the repository.
Preview (a7a8394683)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -10,10 +10,10 @@
reviewers:
- "rjmurillo"
- "mattkotsenas"
- # NuGet dependency management is handled by Renovate (see renovate.json).
- # Dependabot NuGet PRs were disabled because:
- # 1. PR titles use "Bump X from A to B" format, which fails the required
- # "Validate PR title" check (conventional commits required).
- # 2. Both bots created duplicate PRs for every package update.
- # 3. Renovate supports better grouping, automerge rules, and conventional
- # commit formatting out of the box.
+# NuGet dependency management is handled by Renovate (see renovate.json).
+# Dependabot NuGet PRs were disabled because:
+# 1. PR titles use "Bump X from A to B" format, which fails the required
+# "Validate PR title" check (conventional commits required).
+# 2. Both bots created duplicate PRs for every package update.
+# 3. Renovate supports better grouping, automerge rules, and conventional
+# commit formatting out of the box.
diff --git a/.github/labeler.yml b/.github/labeler.yml
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,41 +1,41 @@
# Add 'build' label to any change in the 'build' directory
build:
-- changed-files:
- - any-glob-to-any-file: 'build/**/*'
+ - changed-files:
+ - any-glob-to-any-file: 'build/**/*'
# Add 'dependencies' label to any change in one of the packages files
dependencies:
-- changed-files:
- - any-glob-to-any-file: ['build/**/Packages.props', 'Directory.Packages.props']
+ - changed-files:
+ - any-glob-to-any-file: ['build/**/Packages.props', 'Directory.Packages.props']
# Add 'documentation' label to any change within the 'docs' directory or any '.md' file
documentation:
-- changed-files:
- - any-glob-to-any-file: ['docs/**', '**/*.md']
+ - changed-files:
+ - any-glob-to-any-file: ['docs/**', '**/*.md']
# Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name
feature:
- - head-branch: ['^feature', 'feature']
+ - head-branch: ['^feature', 'feature']
# Add 'bug' label to any PR where the head branch name starts with `bug` or has a `bug` section in the name
bug:
- - head-branch: ['^bug', 'bug']
+ - head-branch: ['^bug', 'bug']
# Add 'releasable' label to any PR that is opened against the `main` branch
releasable:
- - base-branch: 'main'
+ - base-branch: 'main'
# Add 'github_actions' label to any change to one of the GitHub workflows or configuration files
github_actions:
-- changed-files:
- - any-glob-to-any-file: ['.github/workflows/*.yml', '.github/dependabot.yml', '.github/labeler.yml']
+ - changed-files:
+ - any-glob-to-any-file: ['.github/workflows/*.yml', '.github/dependabot.yml', '.github/labeler.yml']
# Add 'analyzers' label to any change to an analyzer, code fix, or shipping documentation
analyzers:
-- changed-files:
- - any-glob-to-any-file: ['src/Moq.Analyzers/AnalyzerReleases.*.md', 'src/Moq.Analyzers/**/*Analyzer.cs', 'src/Moq.Analyzers/**/*CodeFix.cs', 'src/Analyzers/**/*Analyzer.cs', 'src/CodeFixes/*Fixer.cs', 'src/Analyzers/AnalyzerReleases.*.md']
+ - changed-files:
+ - any-glob-to-any-file: ['src/Moq.Analyzers/AnalyzerReleases.*.md', 'src/Moq.Analyzers/**/*Analyzer.cs', 'src/Moq.Analyzers/**/*CodeFix.cs', 'src/Analyzers/**/*Analyzer.cs', 'src/CodeFixes/*Fixer.cs', 'src/Analyzers/AnalyzerReleases.*.md']
# Add 'powershell' label to any change to a PowerShell file
powershell:
-- changed-files:
- - any-glob-to-any-file: ['*.ps1', '*.ps1x', '*.psm1', '*.psd1', '*.ps1xml', '*.pssc', '*.psrc', '*.cdxml']
+ - changed-files:
+ - any-glob-to-any-file: ['*.ps1', '*.ps1x', '*.psm1', '*.psd1', '*.ps1xml', '*.pssc', '*.psrc', '*.cdxml']
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
--- a/.github/workflows/copilot-setup-steps.yml
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -22,7 +22,8 @@
# the above doesn't work as expected, so pre-empt a workaround to avoid agent getting stuck and ignoring instructions in copilot-instructions.md
- name: NBGV workaround
run: git fetch --unshallow
-
+
+
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
diff --git a/.github/workflows/devskim.yml b/.github/workflows/devskim.yml
--- a/.github/workflows/devskim.yml
+++ b/.github/workflows/devskim.yml
@@ -7,9 +7,9 @@
on:
push:
- branches: [ "main" ]
+ branches: ["main"]
pull_request:
- branches: [ "main" ]
+ branches: ["main"]
schedule:
- cron: '32 8 * * 1'
diff --git a/.github/workflows/label-issues.yml b/.github/workflows/label-issues.yml
--- a/.github/workflows/label-issues.yml
+++ b/.github/workflows/label-issues.yml
@@ -22,16 +22,16 @@
// Get the issue body and title
const body = context.payload.issue.body
let title = context.payload.issue.title
-
+
// Define the labels array
let labels = ["triage"]
-
+
// Check if the body or the title contains the word 'PowerShell' (case-insensitive)
if ((body != null && body.match(/powershell/i)) || (title != null && title.match(/powershell/i))) {
// Add the 'powershell' label to the array
labels.push("powershell")
}
-
+
// Check if the body or the title contains the words 'dotnet', '.net', 'c#' or 'csharp' (case-insensitive)
if ((body != null && body.match(/.net/i)) || (title != null && title.match(/.net/i)) ||
(body != null && body.match(/dotnet/i)) || (title != null && title.match(/dotnet/i)) ||
diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml
--- a/.github/workflows/label-pr.yml
+++ b/.github/workflows/label-pr.yml
@@ -18,4 +18,4 @@
steps:
- uses: actions/labeler@v6
with:
- repo-token: "${{ secrets.GH_ACTIONS_PR_WRITE }}"
\ No newline at end of file
+ repo-token: "${{ secrets.GH_ACTIONS_PR_WRITE }}"
diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
new file mode 100644
--- /dev/null
+++ b/.github/workflows/linters.yml
@@ -1,0 +1,40 @@
+name: Lint
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ branches: ["main"]
+
+permissions: {}
+
+jobs:
+ build:
+ name: Lint
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+ packages: read
+ # To report GitHub Actions status checks
+ statuses: write
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ # super-linter needs the full git history to get the
+ # list of files that changed across commits
+ fetch-depth: 0
+
+ - name: Super-linter
+ uses: super-linter/super-linter@61abc07d755095a68f4987d1c2c3d1d64408f1f9 # v8.5.0
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ DEFAULT_BRANCH: main
+ VALIDATE_GITHUB_ACTIONS: true
+ VALIDATE_YAML: true
+ VALIDATE_MARKDOWN: true
+ VALIDATE_JSON: true
+ VALIDATE_BASH: true
+ FILTER_REGEX_EXCLUDE: '\.verified\.(txt|xml|json)$'
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -86,83 +86,83 @@
runs-on: ubuntu-24.04-arm
steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- if: needs.check-paths.outputs.code-changed == 'true'
- with:
- fetch-depth: 0
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ if: needs.check-paths.outputs.code-changed == 'true'
+ with:
+ fetch-depth: 0
- - name: Setup, Restore, and Build Solution
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: ./.github/actions/setup-restore-build
+ - name: Setup, Restore, and Build Solution
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: ./.github/actions/setup-restore-build
- - name: Validate analyzer host compatibility
- if: needs.check-paths.outputs.code-changed == 'true'
- shell: pwsh
- run: |
- # Verify shipped analyzer DLLs don't reference assembly versions
- # exceeding what the minimum supported SDK host (.NET 8) provides.
- # See: https://github.com/rjmurillo/moq.analyzers/issues/850
- $maxVersions = @{
- 'System.Collections.Immutable' = [Version]'8.0.0.0'
- 'System.Reflection.Metadata' = [Version]'8.0.0.0'
- }
- $shippedDlls = @(
- 'artifacts/bin/Moq.Analyzers/release/Moq.Analyzers.dll',
- 'artifacts/bin/Moq.Analyzers/release/Moq.CodeFixes.dll',
- 'artifacts/bin/Moq.Analyzers/release/Microsoft.CodeAnalysis.AnalyzerUtilities.dll'
- )
- $failed = $false
- foreach ($dll in $shippedDlls) {
- $name = [System.IO.Path]::GetFileName($dll)
- $bytes = [System.IO.File]::ReadAllBytes($dll)
- $asm = [System.Reflection.Assembly]::Load($bytes)
- $dllFailed = $false
- foreach ($ref in $asm.GetReferencedAssemblies()) {
- if ($maxVersions.ContainsKey($ref.Name) -and $ref.Version -gt $maxVersions[$ref.Name]) {
- Write-Error "$name references $($ref.Name) $($ref.Version), max allowed is $($maxVersions[$ref.Name])"
- $failed = $true
- $dllFailed = $true
+ - name: Validate analyzer host compatibility
+ if: needs.check-paths.outputs.code-changed == 'true'
+ shell: pwsh
+ run: |
+ # Verify shipped analyzer DLLs don't reference assembly versions
+ # exceeding what the minimum supported SDK host (.NET 8) provides.
+ # See: https://github.com/rjmurillo/moq.analyzers/issues/850
+ $maxVersions = @{
+ 'System.Collections.Immutable' = [Version]'8.0.0.0'
+ 'System.Reflection.Metadata' = [Version]'8.0.0.0'
+ }
+ $shippedDlls = @(
+ 'artifacts/bin/Moq.Analyzers/release/Moq.Analyzers.dll',
+ 'artifacts/bin/Moq.Analyzers/release/Moq.CodeFixes.dll',
+ 'artifacts/bin/Moq.Analyzers/release/Microsoft.CodeAnalysis.AnalyzerUtilities.dll'
+ )
+ $failed = $false
+ foreach ($dll in $shippedDlls) {
+ $name = [System.IO.Path]::GetFileName($dll)
+ $bytes = [System.IO.File]::ReadAllBytes($dll)
+ $asm = [System.Reflection.Assembly]::Load($bytes)
+ $dllFailed = $false
+ foreach ($ref in $asm.GetReferencedAssemblies()) {
+ if ($maxVersions.ContainsKey($ref.Name) -and $ref.Version -gt $maxVersions[$ref.Name]) {
+ Write-Error "$name references $($ref.Name) $($ref.Version), max allowed is $($maxVersions[$ref.Name])"
+ $failed = $true
+ $dllFailed = $true
+ }
}
+ if (-not $dllFailed) { Write-Host "$name - OK" }
}
- if (-not $dllFailed) { Write-Host "$name - OK" }
- }
- if ($failed) { exit 1 }
+ if ($failed) { exit 1 }
- - name: Upload binlogs
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
- with:
- name: binlogs
- path: ./artifacts/logs
- if-no-files-found: error
+ - name: Upload binlogs
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
+ with:
+ name: binlogs
+ path: ./artifacts/logs
+ if-no-files-found: error
- - name: Upload SARIF files
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
- with:
- name: SARIF files
- path: ./artifacts/obj/**/*.sarif
+ - name: Upload SARIF files
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
+ with:
+ name: SARIF files
+ path: ./artifacts/obj/**/*.sarif
- - name: Upload packages
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true'
- with:
- name: packages
- path: |
- ./artifacts/package
- if-no-files-found: error
+ - name: Upload packages
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true'
+ with:
+ name: packages
+ path: |
+ ./artifacts/package
+ if-no-files-found: error
- - name: Upload artifacts
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
- with:
- name: artifacts
- path: ./artifacts
- if-no-files-found: error
+ - name: Upload artifacts
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
+ with:
+ name: artifacts
+ path: ./artifacts
+ if-no-files-found: error
- - name: Skip notice
- if: needs.check-paths.outputs.code-changed != 'true'
- run: echo "Skipped -- no code changes detected"
+ - name: Skip notice
+ if: needs.check-paths.outputs.code-changed != 'true'
+ run: echo "Skipped -- no code changes detected"
# Run unit tests on multiple platforms.
# Build happens independently on each runner so tests use platform-native binaries.
@@ -181,90 +181,90 @@
IS_TARGET_MAIN: ${{ github.ref == 'refs/heads/main' }}
steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- if: needs.check-paths.outputs.code-changed == 'true'
- with:
- fetch-depth: 0
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ if: needs.check-paths.outputs.code-changed == 'true'
+ with:
+ fetch-depth: 0
- - name: Setup, Restore, and Build Solution
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: ./.github/actions/setup-restore-build
+ - name: Setup, Restore, and Build Solution
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: ./.github/actions/setup-restore-build
- - name: Restore Code Coverage history
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
- with:
- name: CoverageHistory-${{ matrix.os }}
- path: ./artifacts/TestResults/coveragehistory
- continue-on-error: true
+ - name: Restore Code Coverage history
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
+ with:
+ name: CoverageHistory-${{ matrix.os }}
+ path: ./artifacts/TestResults/coveragehistory
+ continue-on-error: true
- - name: Test
- if: needs.check-paths.outputs.code-changed == 'true'
- run: dotnet test --no-build --configuration Release --settings ./build/targets/tests/test.runsettings
- env:
- REPORTGENERATOR_LICENSE: ${{ secrets.REPORTGENERATOR_LICENSE }}
+ - name: Test
+ if: needs.check-paths.outputs.code-changed == 'true'
+ run: dotnet test --no-build --configuration Release --settings ./build/targets/tests/test.runsettings
+ env:
+ REPORTGENERATOR_LICENSE: ${{ secrets.REPORTGENERATOR_LICENSE }}
- - name: Upload coverage history
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: >-
- needs.check-paths.outputs.code-changed == 'true'
- && success()
- && env.IS_TARGET_MAIN == 'true'
- with:
- name: CoverageHistory-${{ matrix.os }}
- path: ./artifacts/TestResults/coveragehistory
+ - name: Upload coverage history
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: >-
+ needs.check-paths.outputs.code-changed == 'true'
+ && success()
+ && env.IS_TARGET_MAIN == 'true'
+ with:
+ name: CoverageHistory-${{ matrix.os }}
+ path: ./artifacts/TestResults/coveragehistory
- - name: Upload *.received.* files
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && failure()
- with:
- name: verify-test-results-${{ matrix.os }}
- path: |
- **/*.received.*
+ - name: Upload *.received.* files
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && failure()
+ with:
+ name: verify-test-results-${{ matrix.os }}
+ path: |
+ **/*.received.*
- - name: Upload Test Report
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
- with:
- name: .NET Test Reports (${{ matrix.os }})
- path: "artifacts/TestResults/**/*.trx"
- if-no-files-found: error
+ - name: Upload Test Report
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
+ with:
+ name: .NET Test Reports (${{ matrix.os }})
+ path: "artifacts/TestResults/**/*.trx"
+ if-no-files-found: error
- - name: Upload Code Coverage Report
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
- if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
- with:
- name: .NET Code Coverage Reports (${{ matrix.os }})
- path: "artifacts/TestResults/coverage/**"
+ - name: Upload Code Coverage Report
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
+ if: needs.check-paths.outputs.code-changed == 'true' && (success() || failure())
+ with:
+ name: .NET Code Coverage Reports (${{ matrix.os }})
+ path: "artifacts/TestResults/coverage/**"
- - name: Publish coverage summary to GitHub
- if: needs.check-paths.outputs.code-changed == 'true'
- run: cat artifacts/TestResults/coverage/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
- shell: bash
+ - name: Publish coverage summary to GitHub
+ if: needs.check-paths.outputs.code-changed == 'true'
+ run: cat artifacts/TestResults/coverage/SummaryGithub.md >> $GITHUB_STEP_SUMMARY
+ shell: bash
- - name: Upload coverage data to Codacy
- if: >-
- needs.check-paths.outputs.code-changed == 'true'
- && runner.os == 'Linux'
- && env.IS_CODACY_COVERAGE_ALLOWED == 'true'
- uses: codacy/codacy-coverage-reporter-action@89d6c85cfafaec52c72b6c5e8b2878d33104c699 # v1.3.0
- with:
- project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
- coverage-reports: ${{ github.workspace }}/artifacts/TestResults/coverage/Cobertura.xml
+ - name: Upload coverage data to Codacy
+ if: >-
+ needs.check-paths.outputs.code-changed == 'true'
+ && runner.os == 'Linux'
+ && env.IS_CODACY_COVERAGE_ALLOWED == 'true'
+ uses: codacy/codacy-coverage-reporter-action@89d6c85cfafaec52c72b6c5e8b2878d33104c699 # v1.3.0
+ with:
+ project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
+ coverage-reports: ${{ github.workspace }}/artifacts/TestResults/coverage/Cobertura.xml
- - name: Upload coverage data to Qlty
- if: >-
- needs.check-paths.outputs.code-changed == 'true'
- && runner.os == 'Linux'
- && env.IS_QLTY_COVERAGE_ALLOWED == 'true'
- uses: qltysh/qlty-action/coverage@a19242102d17e497f437d7466aa01b528537e899 # v2
- with:
- token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
- files: ${{ github.workspace }}/artifacts/TestResults/coverage/Cobertura.xml
+ - name: Upload coverage data to Qlty
+ if: >-
+ needs.check-paths.outputs.code-changed == 'true'
+ && runner.os == 'Linux'
+ && env.IS_QLTY_COVERAGE_ALLOWED == 'true'
+ uses: qltysh/qlty-action/coverage@a19242102d17e497f437d7466aa01b528537e899 # v2
+ with:
+ token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
+ files: ${{ github.workspace }}/artifacts/TestResults/coverage/Cobertura.xml
- - name: Skip notice
- if: needs.check-paths.outputs.code-changed != 'true'
- run: echo "Skipped -- no code changes detected"
+ - name: Skip notice
+ if: needs.check-paths.outputs.code-changed != 'true'
+ run: echo "Skipped -- no code changes detected"
# Verify the shipped nupkg loads without CS8032 on every supported host.
# This is the end-to-end integration test for issue #850.
@@ -320,127 +320,127 @@
build-engine: msbuild
steps:
- - name: Setup .NET ${{ matrix.dotnet-version }}
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
- with:
- dotnet-version: ${{ matrix.dotnet-version }}
+ - name: Setup .NET ${{ matrix.dotnet-version }}
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5
+ with:
+ dotnet-version: ${{ matrix.dotnet-version }}
- - name: Setup MSBuild
- if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'msbuild'
- uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2
+ - name: Setup MSBuild
+ if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'msbuild'
+ uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2
- - name: Download nupkg artifact
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
- with:
- name: packages
- path: ./local-feed
+ - name: Download nupkg artifact
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
+ with:
+ name: packages
+ path: ./local-feed
- - name: Create test project
- if: needs.check-paths.outputs.code-changed == 'true'
- shell: pwsh
- run: |
- $pkg = Get-ChildItem ./local-feed -Recurse -Filter 'Moq.Analyzers.*.nupkg' |
- Where-Object { $_.Name -notlike '*.symbols.*' } |
- Select-Object -First 1
- if (-not $pkg) {
- Write-Error "Could not find Moq.Analyzers.*.nupkg (excluding symbols) in ./local-feed"
- exit 1
- }
- $version = $pkg.Name -replace '^Moq\.Analyzers\.' -replace '\.nupkg$'
- $feedDir = (Resolve-Path $pkg.DirectoryName).Path
- Write-Host "Testing Moq.Analyzers $version with ${{ matrix.build-engine }} / ${{ matrix.tfm }}"
- echo "ANALYZER_VERSION=$version" >> $env:GITHUB_ENV
- echo "FEED_DIR=$feedDir" >> $env:GITHUB_ENV
+ - name: Create test project
+ if: needs.check-paths.outputs.code-changed == 'true'
+ shell: pwsh
+ run: |
+ $pkg = Get-ChildItem ./local-feed -Recurse -Filter 'Moq.Analyzers.*.nupkg' |
+ Where-Object { $_.Name -notlike '*.symbols.*' } |
+ Select-Object -First 1
+ if (-not $pkg) {
+ Write-Error "Could not find Moq.Analyzers.*.nupkg (excluding symbols) in ./local-feed"
+ exit 1
+ }
+ $version = $pkg.Name -replace '^Moq\.Analyzers\.' -replace '\.nupkg$'
+ $feedDir = (Resolve-Path $pkg.DirectoryName).Path
+ Write-Host "Testing Moq.Analyzers $version with ${{ matrix.build-engine }} / ${{ matrix.tfm }}"
+ echo "ANALYZER_VERSION=$version" >> $env:GITHUB_ENV
+ echo "FEED_DIR=$feedDir" >> $env:GITHUB_ENV
- New-Item -ItemType Directory -Path test-project | Out-Null
+ New-Item -ItemType Directory -Path test-project | Out-Null
- @"
- <?xml version="1.0" encoding="utf-8"?>
- <configuration>
- <packageSources>
- <clear />
- <add key="local" value="$feedDir" />
- <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
- </packageSources>
- </configuration>
- "@ | Set-Content test-project/nuget.config
+ @"
+ <?xml version="1.0" encoding="utf-8"?>
+ <configuration>
+ <packageSources>
+ <clear />
+ <add key="local" value="$feedDir" />
+ <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
+ </packageSources>
+ </configuration>
+ "@ | Set-Content test-project/nuget.config
- @"
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Library</OutputType>
- <TargetFramework>${{ matrix.tfm }}</TargetFramework>
- <LangVersion>latest</LangVersion>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="Moq.Analyzers" Version="$version" />
- <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
- </ItemGroup>
- </Project>
- "@ | Set-Content test-project/TestAnalyzerLoad.csproj
+ @"
+ <Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>${{ matrix.tfm }}</TargetFramework>
+ <LangVersion>latest</LangVersion>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="Moq.Analyzers" Version="$version" />
+ <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
+ </ItemGroup>
+ </Project>
+ "@ | Set-Content test-project/TestAnalyzerLoad.csproj
- @"
- namespace TestAnalyzerLoad;
- public class Placeholder { }
- "@ | Set-Content test-project/Placeholder.cs
+ @"
+ namespace TestAnalyzerLoad;
+ public class Placeholder { }
+ "@ | Set-Content test-project/Placeholder.cs
- - name: Build with dotnet CLI
- if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'dotnet'
- shell: pwsh
- working-directory: test-project
- run: |
- $output = dotnet build -v n 2>&1 | Out-String
- $buildExitCode = $LASTEXITCODE
- Write-Host $output
+ - name: Build with dotnet CLI
+ if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'dotnet'
+ shell: pwsh
+ working-directory: test-project
+ run: |
+ $output = dotnet build -v n 2>&1 | Out-String
+ $buildExitCode = $LASTEXITCODE
+ Write-Host $output
- if ($buildExitCode -ne 0) {
- Write-Host "::error::Build failed with exit code $buildExitCode (dotnet / ${{ matrix.tfm }})"
- exit $buildExitCode
- }
+ if ($buildExitCode -ne 0) {
+ Write-Host "::error::Build failed with exit code $buildExitCode (dotnet / ${{ matrix.tfm }})"
+ exit $buildExitCode
+ }
- if ($output -match 'CS8032') {
- Write-Host "::error::CS8032: analyzer failed to load (dotnet / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
- exit 1
- }
- if ($output -match '(?i)could not load file or assembly') {
- Write-Host "::error::Assembly binding failure (dotnet / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
- exit 1
- }
+ if ($output -match 'CS8032') {
+ Write-Host "::error::CS8032: analyzer failed to load (dotnet / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
+ exit 1
+ }
+ if ($output -match '(?i)could not load file or assembly') {
+ Write-Host "::error::Assembly binding failure (dotnet / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
+ exit 1
+ }
- Write-Host ""
- Write-Host "Analyzer loaded successfully (dotnet / ${{ matrix.tfm }})"
+ Write-Host ""
+ Write-Host "Analyzer loaded successfully (dotnet / ${{ matrix.tfm }})"
- - name: Build with MSBuild
- if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'msbuild'
- shell: pwsh
- working-directory: test-project
- run: |
- $output = msbuild TestAnalyzerLoad.csproj -restore -p:Configuration=Release -v:n 2>&1 | Out-String
- $buildExitCode = $LASTEXITCODE
- Write-Host $output
+ - name: Build with MSBuild
+ if: needs.check-paths.outputs.code-changed == 'true' && matrix.build-engine == 'msbuild'
+ shell: pwsh
+ working-directory: test-project
+ run: |
+ $output = msbuild TestAnalyzerLoad.csproj -restore -p:Configuration=Release -v:n 2>&1 | Out-String
+ $buildExitCode = $LASTEXITCODE
+ Write-Host $output
- if ($buildExitCode -ne 0) {
- Write-Host "::error::Build failed with exit code $buildExitCode (msbuild / ${{ matrix.tfm }})"
- exit $buildExitCode
- }
+ if ($buildExitCode -ne 0) {
+ Write-Host "::error::Build failed with exit code $buildExitCode (msbuild / ${{ matrix.tfm }})"
+ exit $buildExitCode
+ }
- if ($output -match 'CS8032') {
- Write-Host "::error::CS8032: analyzer failed to load (msbuild / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
- exit 1
- }
- if ($output -match '(?i)could not load file or assembly') {
- Write-Host "::error::Assembly binding failure (msbuild / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
- exit 1
- }
+ if ($output -match 'CS8032') {
+ Write-Host "::error::CS8032: analyzer failed to load (msbuild / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
+ exit 1
+ }
+ if ($output -match '(?i)could not load file or assembly') {
+ Write-Host "::error::Assembly binding failure (msbuild / ${{ matrix.tfm }}). See https://github.com/rjmurillo/moq.analyzers/issues/850"
+ exit 1
+ }
- Write-Host ""
- Write-Host "Analyzer loaded successfully (msbuild / ${{ matrix.tfm }})"
+ Write-Host ""
+ Write-Host "Analyzer loaded successfully (msbuild / ${{ matrix.tfm }})"
- - name: Skip notice
- if: needs.check-paths.outputs.code-changed != 'true'
- run: echo "Skipped -- no code changes detected"
+ - name: Skip notice
+ if: needs.check-paths.outputs.code-changed != 'true'
+ run: echo "Skipped -- no code changes detected"
# Performance validation runs last, after build and tests confirm correctness.
# Builds from source on Linux ARM to get consistent benchmark results.
@@ -453,100 +453,100 @@
FORCE_PERF_BASELINE: ${{ github.event.inputs.force_baseline }}
steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- if: needs.check-paths.outputs.code-changed == 'true'
- with:
- fetch-depth: 0
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ if: needs.check-paths.outputs.code-changed == 'true'
+ with:
+ fetch-depth: 0
- - name: Setup, Restore, and Build Solution
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: ./.github/actions/setup-restore-build
+ - name: Setup, Restore, and Build Solution
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: ./.github/actions/setup-restore-build
- - name: Get baseline SHA
- if: needs.check-paths.outputs.code-changed == 'true'
- id: get-baseline-sha
- run: |
- if (-not (Test-Path build/perf/baseline.json)) {
- Write-Error "baseline.json not found - aborting performance job."
- exit 1
- }
- $baseline = Get-Content build/perf/baseline.json | ConvertFrom-Json
- echo "sha=$($baseline.sha)" >> $env:GITHUB_OUTPUT
- shell: pwsh
+ - name: Get baseline SHA
+ if: needs.check-paths.outputs.code-changed == 'true'
+ id: get-baseline-sha
+ run: |
+ if (-not (Test-Path build/perf/baseline.json)) {
+ Write-Error "baseline.json not found - aborting performance job."
+ exit 1
+ }
+ $baseline = Get-Content build/perf/baseline.json | ConvertFrom-Json
+ echo "sha=$($baseline.sha)" >> $env:GITHUB_OUTPUT
+ shell: pwsh
- # The baseline SHA may require a different .NET SDK version
- - name: Checkout baseline
- if: needs.check-paths.outputs.code-changed == 'true'
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- ref: ${{ steps.get-baseline-sha.outputs.sha }}
- fetch-depth: 0
+ # The baseline SHA may require a different .NET SDK version
+ - name: Checkout baseline
+ if: needs.check-paths.outputs.code-changed == 'true'
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
... diff truncated: showing 800 of 2055 linesThere was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (2)
CONTRIBUTING.md (1)
362-382:⚠️ Potential issue | 🟡 MinorAdd a direct
gh actexample for the new lint workflow.The Local Linting section should include a command that runs
.github/workflows/linters.yml(for example,gh act -W .github/workflows/linters.yml -j build) so contributors can validate the exact CI workflow locally.As per coding guidelines, "Run
gh actlocally to test CI/CD workflows before pushing - verify both locally and in CI that workflows execute successfully."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CONTRIBUTING.md` around lines 362 - 382, Add a direct gh act example to the "Local Linting" section so contributors can run the exact CI lint workflow locally: insert a line showing the command to run `.github/workflows/linters.yml` (e.g. gh act -W .github/workflows/linters.yml -j build) under the existing Docker and linter examples, referencing the workflow file `.github/workflows/linters.yml` and the workflow job name `build` so users can validate the same CI job locally..github/workflows/linters.yml (1)
30-40:⚠️ Potential issue | 🟠 MajorEnable diff-only mode for Super-linter to avoid full-repo scans.
fetch-depth: 0is configured for changed-file detection, butVALIDATE_ALL_CODEBASEis not set. In Super-linter, that typically means full-codebase linting, which can significantly increase CI time.Suggested fix
- name: Super-linter uses: super-linter/super-linter@61abc07d755095a68f4987d1c2c3d1d64408f1f9 # v8.5.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DEFAULT_BRANCH: main + VALIDATE_ALL_CODEBASE: false VALIDATE_GITHUB_ACTIONS: true VALIDATE_YAML: true VALIDATE_MARKDOWN: true VALIDATE_JSON: true VALIDATE_BASH: true FILTER_REGEX_EXCLUDE: '\.verified\.(txt|xml|json)$'As per coding guidelines, "Assess performance impact and ensure changes do not significantly impact CI duration."
For super-linter v8.5.0, what is the default value of VALIDATE_ALL_CODEBASE, and does setting it to false switch linting to changed files only?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/linters.yml around lines 30 - 40, The Super-linter step currently relies on implicit defaults which can trigger full-repo scans; explicitly add the environment variable VALIDATE_ALL_CODEBASE: false under the Super-linter job's env block (the same block containing GITHUB_TOKEN, DEFAULT_BRANCH, VALIDATE_YAML, etc.) so the linter runs in changed-files/diff-only mode; reference the Super-linter step and the env name VALIDATE_ALL_CODEBASE when making this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/copilot-setup-steps.yml:
- Around line 25-26: Remove the extra blank line so only a single blank line
separates the adjacent YAML sections; locate the two consecutive empty lines in
the workflow file's setup steps area and delete one to ensure a single blank
line for consistent yamllint-friendly formatting.
In @.github/workflows/linters.yml:
- Around line 16-19: The permissions block grants packages: read which is
unnecessary for this job; remove the packages: read entry from the permissions
section (i.e., edit the permissions mapping that contains contents: read and
packages: read) so only the minimal required permission(s) remain (e.g.,
contents: read) to tighten job token scope.
In @.yamllint.yml:
- Around line 1-10: The yamllint rule "line-length" currently sets max: 320
which is unusually permissive; either reduce it to a standard limit (e.g., 120)
or add a brief explanatory comment above the rule explaining why 320 is required
(e.g., to accommodate GitHub Actions long inline steps or multiline strings).
Update the .yamllint.yml by editing the "line-length" block (the line-length and
max: 320 entries) and insert a one-line comment describing the rationale if you
intend to keep 320, or change the numeric value to a stricter limit if that was
accidental.
In `@docs/rules/README.md`:
- Around line 39-42: The table row descriptions are mismapped: move the
"restricts As<T> to interfaces" description from the Moq1000-1099 row into the
Moq1300-1399 row, and move the "checks constructor args" part from Moq1200-1299
into the Moq1000-1099 row so constructor-argument checks are documented under
Moq1000-1099; update the four affected rows (Moq1000-1099, Moq1200-1299,
Moq1300-1399) to reflect these swaps and keep wording concise and consistent
with existing documentation patterns.
---
Duplicate comments:
In @.github/workflows/linters.yml:
- Around line 30-40: The Super-linter step currently relies on implicit defaults
which can trigger full-repo scans; explicitly add the environment variable
VALIDATE_ALL_CODEBASE: false under the Super-linter job's env block (the same
block containing GITHUB_TOKEN, DEFAULT_BRANCH, VALIDATE_YAML, etc.) so the
linter runs in changed-files/diff-only mode; reference the Super-linter step and
the env name VALIDATE_ALL_CODEBASE when making this change.
In `@CONTRIBUTING.md`:
- Around line 362-382: Add a direct gh act example to the "Local Linting"
section so contributors can run the exact CI lint workflow locally: insert a
line showing the command to run `.github/workflows/linters.yml` (e.g. gh act -W
.github/workflows/linters.yml -j build) under the existing Docker and linter
examples, referencing the workflow file `.github/workflows/linters.yml` and the
workflow job name `build` so users can validate the same CI job locally.
ℹ️ Review info
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (38)
.github/dependabot.yml.github/labeler.yml.github/workflows/copilot-setup-steps.yml.github/workflows/devskim.yml.github/workflows/label-issues.yml.github/workflows/label-pr.yml.github/workflows/linters.yml.github/workflows/main.yml.github/workflows/milestone-tracking.yml.github/workflows/powershell.yml.github/workflows/pr-labeler-current-milestone.yml.github/workflows/release.yml.markdownlint.json.yamllint.ymlCONTRIBUTING.mddocs/dependency-management.mddocs/rules/Moq1000.mddocs/rules/Moq1001.mddocs/rules/Moq1002.mddocs/rules/Moq1100.mddocs/rules/Moq1101.mddocs/rules/Moq1200.mddocs/rules/Moq1201.mddocs/rules/Moq1202.mddocs/rules/Moq1203.mddocs/rules/Moq1204.mddocs/rules/Moq1206.mddocs/rules/Moq1207.mddocs/rules/Moq1210.mddocs/rules/Moq1300.mddocs/rules/Moq1301.mddocs/rules/Moq1302.mddocs/rules/Moq1400.mddocs/rules/Moq1420.mddocs/rules/Moq1500.mddocs/rules/README.mdsrc/Analyzers/AnalyzerReleases.Shipped.mdsrc/Analyzers/AnalyzerReleases.Unshipped.md
a7a8394 to
030d7de
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.codacy/cli.sh (1)
150-150:⚠️ Potential issue | 🟡 MinorConsider replacing
eval "$run_command $*"with direct execution.Using
evalwith$*can cause issues with argument handling—spaces and special characters in arguments may be misinterpreted, and there's a potential for command injection if arguments contain shell metacharacters.🛡️ Suggested safer alternative
- eval "$run_command $*" + "$run_command" "$@"Using
"$@"preserves individual argument boundaries, and direct execution avoidseval's risks.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.codacy/cli.sh at line 150, The current use of eval with run_command and $* can mangle arguments and allow injection; replace the eval invocation with a direct execution of run_command while passing the original arguments preserved (use "$@" semantics instead of $*), ensuring proper quoting of the arguments and avoiding eval—update the line referencing run_command so it invokes the command directly with the preserved arguments rather than using eval.docs/rules/Moq1200.md (1)
14-14:⚠️ Potential issue | 🟡 MinorTypo: "clas" should be "class".
Line 14 contains a typo: "Mock an interface instead of a clas" should be "Mock an interface instead of a class".
Note: This appears to be a pre-existing issue, not introduced by this PR.
📝 Proposed fix
-- Mock an interface instead of a clas +- Mock an interface instead of a class🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/rules/Moq1200.md` at line 14, Typo: the sentence "Mock an interface instead of a clas" misses an 's' in "class"; update the documentation text to read "Mock an interface instead of a class" by editing the occurrence of the phrase "Mock an interface instead of a clas" in the rule description (Moq1200) so the word "clas" is corrected to "class".
♻️ Duplicate comments (3)
.github/workflows/copilot-setup-steps.yml (1)
25-26: 🧹 Nitpick | 🔵 TrivialExcessive blank lines flagged previously.
Two consecutive blank lines are unnecessary here. Standard YAML formatting uses a single blank line for visual separation between workflow steps.
♻️ Proposed adjustment
- name: NBGV workaround run: git fetch --unshallow - - name: Setup .NET🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/copilot-setup-steps.yml around lines 25 - 26, Remove the extra empty line in the workflow YAML so there is only a single blank line separating steps; find the location where two consecutive blank lines appear between workflow steps (the step boundary in the copilot setup steps) and delete one of them to conform to standard YAML formatting and avoid duplicate blank lines.src/Analyzers/AnalyzerReleases.Shipped.md (1)
8-70:⚠️ Potential issue | 🔴 CriticalBuild failure: Invalid release header format detected by Roslyn Release Tracking Analyzers.
The markdown table format causes RS2007 build failures across all CI platforms (same issue as in AnalyzerReleases.Unshipped.md). The Roslyn Release Tracking Analyzers expect a specific format that differs from standard markdown tables.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/Analyzers/AnalyzerReleases.Shipped.md` around lines 8 - 70, The shipped release file uses Markdown tables that trigger RS2007; update AnalyzerReleases.Shipped.md to use the Roslyn Release Tracking analyzer format (the same non-table format used in AnalyzerReleases.Unshipped.md). Replace each tabular "New Rules"/"Removed Rules" block under release headings (e.g., the blocks containing Moq1101, Moq1002, Moq1001, Moq1003, Moq1100, Moq1000, Moq1200, Moq1300, Moq1201, Moq1400, Moq1410 entries) with the plain-text/line-per-rule format expected by the analyzers so RS2007 no longer fires.docs/rules/README.md (1)
39-42:⚠️ Potential issue | 🟡 MinorCorrect the diagnostic-range example mappings.
The examples are currently cross-mapped:
As<T>belongs inMoq1300-1399, while constructor-argument checks belong inMoq1000-1099.🛠️ Proposed fix
-| Moq1000-1099 | Usage | Prohibits sealed class mocks, restricts As<T> to interfaces | +| Moq1000-1099 | Usage | Prohibits sealed class mocks, checks constructor args | | Moq1100-1199 | Correctness | Ensures callback signatures match, setup is valid | -| Moq1200-1299 | Correctness | Prevents async result setups, checks constructor args | -| Moq1300-1399 | Usage | Restricts use of literals, enforces API usage patterns | +| Moq1200-1299 | Correctness | Prevents async result setups, enforces overridable usage | +| Moq1300-1399 | Usage | Restricts As<T> to interfaces and literal misuse |As per coding guidelines, "Documentation files must use clear, concise language, include code examples, and follow existing documentation patterns."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/rules/README.md` around lines 39 - 42, The diagnostic-range table has cross-mapped examples: move the As<T> (interface casting) example out of Moq1000-1099 into the Moq1300-1399 row and move the constructor-argument checks example from Moq1300-1399 into the Moq1000-1099 row; update the row descriptions so Moq1000-1099 mentions constructor-argument/constructor validation and Moq1300-1399 mentions As<T>/literal/API usage to keep descriptions consistent with the examples.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/instructions/editorconfig.instructions.md:
- Around line 53-54: Update the list entry that currently reads
"[markdown.instructions.md]" to use the proper noun capitalization
"[Markdown.instructions.md]" (i.e., change "markdown" → "Markdown") so the
reference to the Markdown formatting file is correctly capitalized; ensure the
display text in the list uses "Markdown" while leaving the other entry
"[project.instructions.md]" unchanged.
In @.github/instructions/json.instructions.md:
- Line 364: The "Contributor Covenant Code of Conduct" link currently points to
a local folder; update the markdown link target so it points to the repository
root from .github/instructions/ (change the href for the "Contributor Covenant
Code of Conduct" link text to reference the repo-root path, e.g.,
../../CODE-OF-CONDUCT.md) to ensure the link resolves correctly when viewed from
that directory.
In @.github/instructions/text.instructions.md:
- Line 347: The markdown link "Contributor Covenant Code of Conduct" currently
points to a relative path "CODE-OF-CONDUCT.md" that will resolve incorrectly
from .github/instructions; update that link to the repository-root-relative path
(e.g. "/CODE-OF-CONDUCT.md") so it resolves correctly from any subdirectory,
leaving the link text unchanged.
In @.github/instructions/xml.instructions.md:
- Line 362: Update the markdown link for "Contributor Covenant Code of Conduct"
to point to the repository root file (replace the current "CODE-OF-CONDUCT.md"
reference in the line containing "This project adheres to the [Contributor
Covenant Code of Conduct](CODE-OF-CONDUCT.md)." with the correct relative path
from .github/instructions/, i.e. "../../CODE-OF-CONDUCT.md") so the link
resolves from .github/instructions/.
In @.github/instructions/yaml.instructions.md:
- Line 352: Update the relative link target "CODE-OF-CONDUCT.md" in the line
containing "Contributor Covenant Code of Conduct" to point to the repository
root (use "/CODE-OF-CONDUCT.md" or an appropriate absolute path) so the link
resolves correctly from .github/instructions; replace the existing link target
with "/CODE-OF-CONDUCT.md" wherever that exact text appears.
In @.github/workflows/pr-labeler-current-milestone.yml:
- Around line 14-18: Remove the extra blank line before the "Label PRs" step so
the first step immediately follows steps:, i.e., adjust the block containing
"uses: actions/labeler@v6" and its "with:"/ "pr-number:" keys to start without
the leading empty line; ensure the YAML indentation and grouping for the action
(uses: actions/labeler@v6, with:, pr-number:) remain unchanged.
In @.markdownlint.json:
- Around line 1-6: Add documentation explaining why each markdownlint rule
(MD013, MD024, MD033, MD041) is disabled by creating a companion file (e.g.,
.markdownlint.md) or converting .markdownlint.json to a commented-capable format
like .markdownlint.yaml; in that companion file list each rule (MD013, MD024,
MD033, MD041) and a short rationale (e.g., MD013: allow long code examples,
MD024: duplicate headings across examples, MD033: permit inline HTML for
collapsible sections, MD041: frontmatter-first-heading conflict) so future
maintainers can see the intent without changing the existing rule keys.
In `@build/scripts/perf/CIPerf.sh`:
- Line 9: Replace the pwsh invocation that uses -command and unquoted $* with a
-File invocation and "$@" so arguments with spaces are preserved: update the
line calling PerfCore.ps1 (referencing SCRIPT_DIR and PerfCore.ps1 in CIPerf.sh)
from using -command "& \"$SCRIPT_DIR/PerfCore.ps1\" -v diag -diff -ci $*" to
using -File "$SCRIPT_DIR/PerfCore.ps1" -v diag -diff -ci "$@" while keeping the
existing -ExecutionPolicy ByPass -NoProfile flags.
In `@Perf.sh`:
- Line 9: The pwsh call in Perf.sh currently uses $* which breaks arguments with
spaces; update the invocation to preserve argument boundaries by passing the
script with -File and forwarding quoted args using "$@". Replace the line that
calls pwsh (the one invoking "$SCRIPT_DIR/build/scripts/perf/PerfCore.ps1") so
it uses: pwsh -ExecutionPolicy ByPass -NoProfile -File
"$SCRIPT_DIR/build/scripts/perf/PerfCore.ps1" "$@"; this ensures arguments like
"my project" or "*Bench*" are passed intact to PerfCore.ps1.
---
Outside diff comments:
In @.codacy/cli.sh:
- Line 150: The current use of eval with run_command and $* can mangle arguments
and allow injection; replace the eval invocation with a direct execution of
run_command while passing the original arguments preserved (use "$@" semantics
instead of $*), ensuring proper quoting of the arguments and avoiding
eval—update the line referencing run_command so it invokes the command directly
with the preserved arguments rather than using eval.
In `@docs/rules/Moq1200.md`:
- Line 14: Typo: the sentence "Mock an interface instead of a clas" misses an
's' in "class"; update the documentation text to read "Mock an interface instead
of a class" by editing the occurrence of the phrase "Mock an interface instead
of a clas" in the rule description (Moq1200) so the word "clas" is corrected to
"class".
---
Duplicate comments:
In @.github/workflows/copilot-setup-steps.yml:
- Around line 25-26: Remove the extra empty line in the workflow YAML so there
is only a single blank line separating steps; find the location where two
consecutive blank lines appear between workflow steps (the step boundary in the
copilot setup steps) and delete one of them to conform to standard YAML
formatting and avoid duplicate blank lines.
In `@docs/rules/README.md`:
- Around line 39-42: The diagnostic-range table has cross-mapped examples: move
the As<T> (interface casting) example out of Moq1000-1099 into the Moq1300-1399
row and move the constructor-argument checks example from Moq1300-1399 into the
Moq1000-1099 row; update the row descriptions so Moq1000-1099 mentions
constructor-argument/constructor validation and Moq1300-1399 mentions
As<T>/literal/API usage to keep descriptions consistent with the examples.
In `@src/Analyzers/AnalyzerReleases.Shipped.md`:
- Around line 8-70: The shipped release file uses Markdown tables that trigger
RS2007; update AnalyzerReleases.Shipped.md to use the Roslyn Release Tracking
analyzer format (the same non-table format used in
AnalyzerReleases.Unshipped.md). Replace each tabular "New Rules"/"Removed Rules"
block under release headings (e.g., the blocks containing Moq1101, Moq1002,
Moq1001, Moq1003, Moq1100, Moq1000, Moq1200, Moq1300, Moq1201, Moq1400, Moq1410
entries) with the plain-text/line-per-rule format expected by the analyzers so
RS2007 no longer fires.
ℹ️ Review info
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (56)
.codacy/cli.sh.github/actionlint.yaml.github/copilot-instructions.md.github/dependabot.yml.github/instructions/README.md.github/instructions/csharp.instructions.md.github/instructions/editorconfig.instructions.md.github/instructions/generic.instructions.md.github/instructions/gitignore.instructions.md.github/instructions/json.instructions.md.github/instructions/markdown.instructions.md.github/instructions/msbuild.instructions.md.github/instructions/project.instructions.md.github/instructions/shell.instructions.md.github/instructions/text.instructions.md.github/instructions/xml.instructions.md.github/instructions/yaml.instructions.md.github/labeler.yml.github/workflows/copilot-setup-steps.yml.github/workflows/devskim.yml.github/workflows/label-issues.yml.github/workflows/label-pr.yml.github/workflows/linters.yml.github/workflows/main.yml.github/workflows/milestone-tracking.yml.github/workflows/powershell.yml.github/workflows/pr-labeler-current-milestone.yml.github/workflows/release.yml.markdownlint.json.yamllint.ymlCONTRIBUTING.mdPerf.shbuild/scripts/perf/CIPerf.shdocs/dependency-management.mddocs/rules/Moq1000.mddocs/rules/Moq1001.mddocs/rules/Moq1002.mddocs/rules/Moq1100.mddocs/rules/Moq1101.mddocs/rules/Moq1200.mddocs/rules/Moq1201.mddocs/rules/Moq1202.mddocs/rules/Moq1203.mddocs/rules/Moq1204.mddocs/rules/Moq1206.mddocs/rules/Moq1207.mddocs/rules/Moq1210.mddocs/rules/Moq1300.mddocs/rules/Moq1301.mddocs/rules/Moq1302.mddocs/rules/Moq1400.mddocs/rules/Moq1420.mddocs/rules/Moq1500.mddocs/rules/README.mdsrc/Analyzers/AnalyzerReleases.Shipped.mdsrc/Analyzers/AnalyzerReleases.Unshipped.md
030d7de to
b32135c
Compare
b32135c to
a7e7f3a
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: YAML linter config file not explicitly referenced
- Added YAML_YAMLLINT_FILE_NAME: ".yamllint.yml" to the super-linter workflow to ensure the custom YAML config is used instead of the default .yaml-lint.yml.
Preview (247f185d66)
diff --git a/.codacy/cli.sh b/.codacy/cli.sh
--- a/.codacy/cli.sh
+++ b/.codacy/cli.sh
@@ -37,7 +37,8 @@
get_version_from_yaml() {
if [ -f "$version_file" ]; then
- local version=$(grep -o 'version: *"[^"]*"' "$version_file" | cut -d'"' -f2)
+ local version
+ version=$(grep -o 'version: *"[^"]*"' "$version_file" | cut -d'"' -f2)
if [ -n "$version" ]; then
echo "$version"
return 0
@@ -55,7 +56,8 @@
fi
handle_rate_limit "$response"
- local version=$(echo "$response" | grep -m 1 tag_name | cut -d'"' -f4)
+ local version
+ version=$(echo "$response" | grep -m 1 tag_name | cut -d'"' -f4)
echo "$version"
}
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -3,7 +3,7 @@
## 🚩 Quick Reference: Critical Rules for AI Agents
| Rule | Requirement |
-|------|-------------|
+| ------ | ------------- |
| .NET/C# Target | All C# code must target .NET 9 and C# 13; Analyzers and CodeFix must target .NET Standard 2.0 |
| No Trial-and-Error | Never guess or use trial-and-error; STOP if unsure |
| Test Coverage | All changes must be covered by tests (including edge/failure paths) |
@@ -49,7 +49,6 @@
### 1. Pre-Implementation Expertise Validation
-
---
## Escalation and Stop Conditions
@@ -65,15 +64,18 @@
### Symbol-Based Detection (MANDATORY)
**Always prefer symbol-based detection over string matching:**
+
- ✅ Use `ISymbol` and `SemanticModel.GetSymbolInfo()` for type-safe detection
- ✅ Register types in `MoqKnownSymbols` using `TypeProvider.GetOrCreateTypeByMetadataName()`
- ❌ Avoid string-based method name matching (fragile, not refactoring-safe)
**Generic Type Handling:**
+
- Use backtick notation for generic arity: `"Moq.Language.IRaise\`1"` for `IRaise<T>`
- Collect method overloads: `GetMembers("MethodName").OfType<IMethodSymbol>().ToImmutableArray()`
**Moq Fluent API Chain Pattern:**
+
- Moq methods return different interfaces at different chain positions
- Example: `Setup()` → `ISetup<T>` → `.Raises()` → `IRaise<T>` → `.Returns()` → `IReturns<T>`
- **Register ALL interfaces in the chain**, not just endpoint types
@@ -81,6 +83,7 @@
### Diagnostic Investigation Pattern
When tests fail after removing string-based detection:
+
1. Create temporary diagnostic test using `SemanticModel.GetSymbolInfo()`
2. Capture actual symbol type at runtime
3. Compare against `MoqKnownSymbols` registry to find missing entries
@@ -89,6 +92,7 @@
### Context Preservation
Use appropriate analysis contexts to maintain compilation access:
+
- `SyntaxNodeAnalysisContext` - For syntax tree analysis with semantic model
- `SemanticModelAnalysisContext` - For semantic analysis
- `SyntaxTreeAnalysisContext` - For whole-file analysis
@@ -96,6 +100,7 @@
---
**Implementation:**
+
- Answer domain-specific technical questions before coding
- Provide concrete examples of your understanding
- Request expert guidance if uncertain about any concept
@@ -111,6 +116,7 @@
- **Stop progression** if any required step is incomplete
**Implementation:**
+
- Read and understand project-specific instructions first
- Follow established patterns and conventions
- Verify each workflow step was completed successfully
@@ -119,12 +125,14 @@
### 3. Critical Failure Recognition
**You MUST establish clear stop conditions:**
+
- **Immediate halt** for uncertainty or lack of understanding
- **Specific criteria** for when to request expert guidance
- **No trial-and-error tolerance** - require deliberate, correct understanding
- **Clear escalation paths** when encountering complex situations
**Implementation:**
+
- Stop immediately if you cannot explain your approach
- Request expert guidance when uncertain about domain concepts
- Never attempt to "figure out" solutions through guessing
@@ -133,12 +141,14 @@
### 4. Tool Usage Reliability
**You MUST use available tools consistently and reliably:**
+
- **Consistent, reliable use** of available tools regardless of platform
- **Graceful handling** of tool failures and interruptions
- **Validation** that tools were used correctly and effectively
- **Retry mechanisms** for interrupted operations
**Implementation:**
+
- Use tools systematically and consistently
- Handle tool failures gracefully with clear error messages
- Validate tool outputs before proceeding
@@ -147,12 +157,14 @@
### 5. Context and State Management
**You MUST preserve context and maintain state:**
+
- **Preserve context** across task interruptions or resumptions
- **Maintain state** during complex multi-step operations
- **Automatic recovery** of context after interruptions
- **Clear state transitions** between different phases of work
**Implementation:**
+
- Maintain clear state throughout complex operations
- Recover context automatically after interruptions
- Document state transitions clearly
@@ -161,12 +173,14 @@
### 6. Documentation and Configuration Awareness
**You MUST check and understand project context:**
+
- **Check relevant files** before making changes
- **Read and understand** project-specific instructions
- **Follow established patterns** and conventions
- **Respect existing architecture** and design decisions
**Implementation:**
+
- Always read configuration files and documentation first
- Understand project structure and conventions
- Follow established naming and architectural patterns
@@ -175,12 +189,14 @@
### 7. Validation and Verification
**You MUST verify work through appropriate means:**
+
- **Verify work** through appropriate means (tests, analysis, etc.)
- **Confirm changes** meet requirements before considering tasks complete
- **Run validation checks** after modifications
- **Ensure quality** through systematic verification
**Implementation:**
+
- Run tests and validation checks after changes
- Verify that modifications meet stated requirements
- Use appropriate verification methods for the domain
@@ -189,12 +205,14 @@
### 8. No Trial-and-Error Tolerance
**You MUST require deliberate understanding:**
+
- **Require deliberate understanding** before implementation
- **No guessing** at solutions or approaches
- **Clear escalation paths** when uncertain
- **Expert guidance triggers** for complex or unclear situations
**Implementation:**
+
- Never implement solutions you don't fully understand
- Stop and request clarification when uncertain
- Establish clear criteria for when to seek expert guidance
@@ -279,7 +297,6 @@
5. **Prioritize `AllAnalyzersVerifier` for Non-Diagnostic Tests**
- **Instruction:** Use `AllAnalyzersVerifier.VerifyAllAnalyzersAsync()` for "no diagnostics" tests.
-
### AI Agent Workflow
When making changes, follow this workflow:
@@ -304,7 +321,6 @@
---
-
### AI Agent Specific Output Checklist
- Output only complete, compiling code (classes or methods) with all required `using` directives.
@@ -320,7 +336,7 @@
All commits must use the [Conventional Commits](https://www.conventionalcommits.org/) format:
-```
+```text
<type>[optional scope]: <description>
[optional body]
@@ -335,6 +351,7 @@
- `docs(readme): update installation instructions`
**Bad:**
+
- `fixed bug on landing page`
- `oops`
- `I think I fixed it this time?`
@@ -356,6 +373,7 @@
Before writing a single line of code, you must internally verify you can make the following declaration. If not, you must halt immediately.
> "I declare that I have expert-level, demonstrable expertise in:
+>
> - Roslyn syntax tree navigation from `SyntaxNode` down to `SyntaxToken` and `SyntaxTrivia`.
> - Precise, character-level diagnostic span calculation and verification.
> - The distinction and correct application of `IOperation` vs. `ISyntaxNode` analysis.
@@ -435,13 +453,13 @@
---
-
## AI Agent Code Review
I need your help tracking down and fixing some bugs that have been reported in this codebase.
I suspect the bugs are related to:
-- Incorrect handling of edge cases
+
+- Incorrect handling of edge cases
- Off-by-one errors in loops or array indexing
- Unexpected data types
- Uncaught exceptions
@@ -449,17 +467,19 @@
- Improper configuration settings
To diagnose:
-1. Review the code carefully and systematically
-2. Trace the relevant code paths
+
+1. Review the code carefully and systematically
+2. Trace the relevant code paths
3. Consider boundary conditions and potential error states
4. Look for antipatterns that tend to cause bugs
-5. Run the code mentally with example inputs
+5. Run the code mentally with example inputs
6. Think about interactions between components
When you find potential bugs, for each one provide:
+
1. File path and line number(s)
2. Description of the issue and why it's a bug
-3. Example input that would trigger the bug
+3. Example input that would trigger the bug
4. Suggestions for how to fix it
After analysis, please update the code with your proposed fixes. Try to match the existing code style. Add regression tests if possible, to prevent the bugs from recurring.
@@ -527,6 +547,7 @@
5. **Test coverage** - Ensure all file types have appropriate instruction coverage
**Common areas requiring updates across multiple files:**
+
- Git commit message guidelines
- Pull request requirements
- Code quality standards
@@ -543,6 +564,7 @@
## Reference to General Guidelines
For comprehensive contributor guidance including:
+
- Development workflow requirements
- Code quality standards
- Testing requirements and patterns
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -10,10 +10,10 @@
reviewers:
- "rjmurillo"
- "mattkotsenas"
- # NuGet dependency management is handled by Renovate (see renovate.json).
- # Dependabot NuGet PRs were disabled because:
- # 1. PR titles use "Bump X from A to B" format, which fails the required
- # "Validate PR title" check (conventional commits required).
- # 2. Both bots created duplicate PRs for every package update.
- # 3. Renovate supports better grouping, automerge rules, and conventional
- # commit formatting out of the box.
+# NuGet dependency management is handled by Renovate (see renovate.json).
+# Dependabot NuGet PRs were disabled because:
+# 1. PR titles use "Bump X from A to B" format, which fails the required
+# "Validate PR title" check (conventional commits required).
+# 2. Both bots created duplicate PRs for every package update.
+# 3. Renovate supports better grouping, automerge rules, and conventional
+# commit formatting out of the box.
diff --git a/.github/instructions/README.md b/.github/instructions/README.md
--- a/.github/instructions/README.md
+++ b/.github/instructions/README.md
@@ -2,19 +2,19 @@
This table maps file patterns in the repository to their corresponding instruction files. Use this as a quick reference to ensure you are following the correct guidance for each file type. If a file type is not listed, refer to `generic.instructions.md`.
-| File Pattern | Instruction File | Description/Notes |
-|------------------------|----------------------------------------------------|-----------------------------------------|
-| `*.cs` | `csharp.instructions.md` | C# source files |
-| `*.csproj`, `*.sln` | `project.instructions.md` | Project/solution files |
-| `*.md` | `markdown.instructions.md` | Markdown documentation |
-| `*.json` | `json.instructions.md` | JSON config |
-| `*.yml`, `*.yaml` | `yaml.instructions.md` | CI/CD workflows |
-| `*.sh`, `*.ps1` | `shell.instructions.md` | Shell/PowerShell scripts |
-| `*.xml` | `xml.instructions.md` | XML config/docs |
-| `*.txt` | `text.instructions.md` | Text files |
-| `.editorconfig` | `editorconfig.instructions.md` | EditorConfig rules |
-| `.gitignore` | `gitignore.instructions.md` | Git ignore rules |
-| `*.props`, `*.targets` | `msbuild.instructions.md` | MSBuild property/target files |
-| _Other_ | `generic.instructions.md` | Fallback for unknown file types |
+| File Pattern | Instruction File | Description/Notes |
+| --- | --- | --- |
\ No newline at end of file
+| `*.cs` | `csharp.instructions.md` | C# source files |
+| `*.csproj`, `*.sln` | `project.instructions.md` | Project/solution files |
+| `*.md` | `markdown.instructions.md` | Markdown documentation |
+| `*.json` | `json.instructions.md` | JSON config |
+| `*.yml`, `*.yaml` | `yaml.instructions.md` | CI/CD workflows |
+| `*.sh`, `*.ps1` | `shell.instructions.md` | Shell/PowerShell scripts |
+| `*.xml` | `xml.instructions.md` | XML config/docs |
+| `*.txt` | `text.instructions.md` | Text files |
+| `.editorconfig` | `editorconfig.instructions.md` | EditorConfig rules |
+| `.gitignore` | `gitignore.instructions.md` | Git ignore rules |
+| `*.props`, `*.targets` | `msbuild.instructions.md` | MSBuild property/target files |
+| _Other_ | `generic.instructions.md` | Fallback for unknown file types |
-**Note:** If you are editing a file type not listed above, always check for a matching instruction file in this directory or use the generic fallback. When in doubt, escalate by tagging `@repo-maintainers` in your PR.
+**Note:** If you are editing a file type not listed above, always check for a matching instruction file in this directory or use the generic fallback. When in doubt, escalate by tagging `@repo-maintainers` in your PR.
diff --git a/.github/instructions/csharp.instructions.md b/.github/instructions/csharp.instructions.md
--- a/.github/instructions/csharp.instructions.md
+++ b/.github/instructions/csharp.instructions.md
@@ -8,9 +8,10 @@
- **For complex changes, see the Decision Trees section below**
-**MANDATORY: Only Valid C# Code in All Tests**
+## MANDATORY: Only Valid C# Code in All Tests
> **You MUST NEVER write or include code in analyzer or code fix tests that produces C# compiler errors.**
+>
> - All test code must be valid, compilable C#.
> - Do not write tests for static, const, readonly, or event members if the code would not compile.
> - Do not include code that triggers CSxxxx errors (e.g., invalid member access, missing members, or illegal syntax).
@@ -18,6 +19,7 @@
> - Any test that fails to compile is an immediate failure and must be removed or rewritten.
**Rationale:**
+
- Roslyn analyzers and code fixes only operate on valid, successfully parsed C# code. Compiler errors prevent analyzers from running and invalidate the test scenario.
- Writing invalid code in tests causes build failures, test failures, and wastes review/CI resources.
- This is a non-negotiable rule. If you are unsure whether a test is valid C#, STOP and request expert guidance.
@@ -94,23 +96,24 @@
If tests fail after adding/modifying symbol-based detection:
1. **Create Temporary Diagnostic Test:**
-```csharp
-[TestMethod]
-public async Task DiagnosticSymbolTest()
-{
- string code = """
- var mock = new Mock<ITestInterface>();
- mock.Setup(x => x.Method()).Raises(x => x.Event += null, EventArgs.Empty);
- """;
-
- var (compilation, semanticModel, invocation) = await GetSemanticInfo(code);
- var symbolInfo = semanticModel.GetSymbolInfo(invocation);
-
- // Output actual symbol type to understand what's missing
- Console.WriteLine($"Symbol: {symbolInfo.Symbol?.ContainingType}");
-}
-```
+ ```csharp
+ [TestMethod]
+ public async Task DiagnosticSymbolTest()
+ {
+ string code = """
+ var mock = new Mock<ITestInterface>();
+ mock.Setup(x => x.Method()).Raises(x => x.Event += null, EventArgs.Empty);
+ """;
+
+ var (compilation, semanticModel, invocation) = await GetSemanticInfo(code);
+ var symbolInfo = semanticModel.GetSymbolInfo(invocation);
+
+ // Output actual symbol type to understand what's missing
+ Console.WriteLine($"Symbol: {symbolInfo.Symbol?.ContainingType}");
+ }
+ ```
+
2. **Compare Against Registry:** Check if symbol type exists in `MoqKnownSymbols`
3. **Add Missing Symbol:** Register in `MoqKnownSymbols` with proper generic arity
4. **Delete Diagnostic Test:** Always clean up temporary investigation code
@@ -124,6 +127,7 @@
## Test Data & Sample Inputs/Outputs
### What Constitutes Good Test Data?
+
- Cover all code paths: positive, negative, and edge cases
- Include both minimal and complex/realistic examples
- Test for invalid inputs, exceptions, and boundary conditions
@@ -131,6 +135,7 @@
- For analyzers/code fixes: test all diagnostic locations, fix applications, and no-fix scenarios
### Coverage Strategy
+
- For every new analyzer/code fix, include:
- At least one positive, one negative, and one edge case test
- Data-driven tests for all fixable patterns
diff --git a/.github/instructions/editorconfig.instructions.md b/.github/instructions/editorconfig.instructions.md
--- a/.github/instructions/editorconfig.instructions.md
+++ b/.github/instructions/editorconfig.instructions.md
@@ -13,6 +13,7 @@
## Context Loading for Copilot
When working on this file, you MUST:
+
1. Read this entire instruction file before making any changes
2. Validate your understanding by checking the "Validation Checklist" section
3. If uncertain about any requirement, stop and request clarification
@@ -23,6 +24,7 @@
## Validation Checklist
Before submitting any changes, verify:
+
- [ ] All formatting and linting rules are correct and documented
- [ ] All changes are compatible with project coding standards
- [ ] All affected files are re-formatted and linted
@@ -30,6 +32,7 @@
- [ ] PR description includes validation evidence and checklist
## Validation Evidence Requirements
+
- Attach a log section titled `## EditorConfig Validation Log` showing the output of `dotnet format` or equivalent
- Include a checklist like:
- [x] All files formatted
@@ -37,6 +40,7 @@
- Paste CI run link under `## CI Evidence`
## .editorconfig Guidance
+
- .editorconfig controls code formatting and linting for the repository
- Changes may affect build results, code reviews, and CI
- Only update rules when necessary and after confirming with maintainers
@@ -44,6 +48,7 @@
- Document any rule changes in the PR description
## Related Instruction Files
+
- [csharp.instructions.md](csharp.instructions.md) - For C# code formatting
- [markdown.instructions.md](markdown.instructions.md) - For markdown formatting
\ No newline at end of file
-- [project.instructions.md](project.instructions.md) - For build configuration
+- [project.instructions.md](project.instructions.md) - For build configuration
diff --git a/.github/instructions/generic.instructions.md b/.github/instructions/generic.instructions.md
--- a/.github/instructions/generic.instructions.md
+++ b/.github/instructions/generic.instructions.md
@@ -14,6 +14,7 @@
## Context Loading for Copilot
When working on this file, you MUST:
+
1. Read this entire instruction file before making any changes
2. Validate your understanding by checking the "Validation Checklist" section
3. If uncertain about any requirement, stop and request clarification
@@ -24,26 +25,30 @@
## Validation Checklist
Before submitting any changes, verify:
+
- [ ] All changes are compatible with project requirements
- [ ] No breaking changes to build, test, or deployment
- [ ] Machine-readable evidence is attached (see below)
- [ ] PR description includes validation evidence and checklist
## Validation Evidence Requirements
+
- Attach a log section titled `## Validation Log` showing the output of any relevant validation commands (build, test, lint, etc.)
- Include a checklist like:
- [x] No errors or warnings
- Paste CI run link under `## CI Evidence`
## Guidance
+
- If you are unsure how to edit this file type, consult maintainers before proceeding
- Document any changes in the PR description
## Related Instruction Files
+
- [project.instructions.md](project.instructions.md) - For project/solution files
- [csharp.instructions.md](csharp.instructions.md) - For C# files
- [markdown.instructions.md](markdown.instructions.md) - For documentation
-- [shell.instructions.md](shell.instructions.md) - For scripts
+- [shell.instructions.md](shell.instructions.md) - For scripts
## Decision Trees for Complex Scenarios
@@ -80,16 +85,18 @@
6. **Run all validations (build, test, lint, Codacy, etc.)**
7. **Prepare PR with validation evidence for each file type**
8. **If any diagnostic span or test fails more than once, STOP and escalate**
-9. **If uncertain about Roslyn APIs, Moq semantics, or workflow, escalate**
+9. **If uncertain about Roslyn APIs, Moq semantics, or workflow, escalate**
## Test Data & Sample Inputs/Outputs
### What Constitutes Good Test Data for Unknown File Types?
+
- Validate file with any available tool (lint, build, CI, etc.)
- Include both valid and invalid examples if possible
- Test for missing required content, invalid formats, and edge cases
- Document test data rationale in comments or PR description
### Coverage Strategy
\ No newline at end of file
+
- For every change, validate with available tools and test both valid and invalid cases
-- Document test data rationale in comments or PR description
+- Document test data rationale in comments or PR description
diff --git a/.github/instructions/gitignore.instructions.md b/.github/instructions/gitignore.instructions.md
--- a/.github/instructions/gitignore.instructions.md
+++ b/.github/instructions/gitignore.instructions.md
@@ -13,6 +13,7 @@
## Context Loading for Copilot
When working on this file, you MUST:
+
1. Read this entire instruction file before making any changes
2. Validate your understanding by checking the "Validation Checklist" section
3. If uncertain about any requirement, stop and request clarification
@@ -23,6 +24,7 @@
## Validation Checklist
Before submitting any changes, verify:
+
- [ ] Only files that should not be tracked are ignored
- [ ] No source, config, or required files are ignored
- [ ] All new build artifacts, logs, and secrets are ignored
@@ -30,6 +32,7 @@
- [ ] PR description includes validation evidence and checklist
## Validation Evidence Requirements
+
- Attach a log section titled `## Gitignore Validation Log` showing the output of `git status` before and after changes
- Include a checklist like:
- [x] No required files ignored
@@ -37,6 +40,7 @@
- Paste CI run link under `## CI Evidence`
## .gitignore Guidance
+
- Only ignore files that are not needed in the repository (build output, logs, secrets, etc.)
- Never ignore source code, configuration, or documentation files
- Review changes with maintainers if unsure
@@ -44,5 +48,6 @@
- Document any changes in the PR description
## Related Instruction Files
+
- [project.instructions.md](project.instructions.md) - For build artifacts
\ No newline at end of file
-- [text.instructions.md](text.instructions.md) - For text file patterns
+- [text.instructions.md](text.instructions.md) - For text file patterns
diff --git a/.github/instructions/json.instructions.md b/.github/instructions/json.instructions.md
--- a/.github/instructions/json.instructions.md
+++ b/.github/instructions/json.instructions.md
@@ -12,12 +12,14 @@
## Context Loading for Copilot
When working on this file type, you MUST:
+
1. Read this entire instruction file before making any changes
2. Cross-reference with related instruction files (listed below)
3. Validate your understanding by checking the "Validation Checklist" section
4. If uncertain about any requirement, stop and request clarification
**Related Instruction Files:**
+
- [project.instructions.md](project.instructions.md) - For project and build configuration
- [yaml.instructions.md](yaml.instructions.md) - For CI/CD workflows
- [text.instructions.md](text.instructions.md) - For plain text configuration
@@ -27,12 +29,14 @@
Before submitting any changes, verify:
**Configuration:**
+
- [ ] JSON syntax is valid
- [ ] Schema compliance is maintained
- [ ] All configuration standards followed
- [ ] Security scan completed after dependency changes
**Process:**
+
- [ ] Conventional commit format used
- [ ] PR description includes validation evidence
- [ ] All checklist items completed
@@ -41,11 +45,13 @@
## Decision Trees
### When to Request Human Review
+
- Is this a new configuration standard? → Yes → Request expert guidance
- Is this a breaking change to configuration? → Yes → Document thoroughly and request review
- Are you uncertain about JSON schema or configuration? → Yes → Stop and request guidance
### When to Stop and Ask for Help
+
- Uncertain about configuration requirements
- Major changes to project configuration
- Security or legal implications
@@ -53,11 +59,13 @@
## Common Mistakes to Avoid
**DO NOT:**
+
- Skip validation steps
- Ignore security scanning after dependency changes
- Submit changes without validation evidence
**ALWAYS:**
+
- Read the entire instruction file first
- Validate all configuration changes
- Include comprehensive documentation updates
@@ -66,16 +74,19 @@
## Context Management
**Before Starting:**
+
- Read the complete instruction file
- Understand the current file's purpose and structure
- Identify all related files that may need updates
**During Editing:**
+
- Keep track of all changes made
- Validate each change against requirements
- Maintain consistency with existing patterns
**After Completing:**
+
- Review all changes against the validation checklist
- Ensure all requirements are met
- Prepare comprehensive PR description with evidence
@@ -83,12 +94,14 @@
## Handling Uncertainty
**Stop and Request Help When:**
+
- You cannot explain your approach clearly
- You're making "educated guesses" about configuration
- You're uncertain about project configuration
- You cannot trace the logic in configuration without narration
**Escalation Process:**
+
1. Stop all work immediately
2. Document what you were trying to accomplish
3. Explain what specific aspect is unclear
@@ -98,6 +111,7 @@
## Success Criteria
Your changes are successful when:
+
- All configuration validation checks pass
- Security scan is clean
- PR description is complete and accurate
@@ -155,6 +169,7 @@
### Dependency Update Guidelines
**For Renovate/Dependabot PRs:**
+
- Review changelog and release notes
- Test locally to ensure compatibility
- Check for breaking changes
@@ -162,6 +177,7 @@
- Include testing evidence in PR description
**For Manual Dependency Updates:**
+
- Follow the same process as automated updates
- Document the reason for the update
- Include compatibility testing results
@@ -222,7 +238,7 @@
Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
-```
+```text
<type>[optional scope]: <description>
[optional body]
@@ -231,6 +247,7 @@Types:
+
feat: New featuresfix: Bug fixesdocs: Documentation changes
@@ -250,6 +267,7 @@
Follow conventional commit format:type(scope): description
Description Requirements:
+
- Clear summary of changes
- Problem statement (what issue does this solve?)
- Solution description (how does this solve the problem?)
@@ -271,12 +289,14 @@
Validation Evidence Requirements
What Constitutes Validation Evidence:
+
- JSON validation output
- Configuration testing results
- Screenshots of successful CI runs
- Manual testing results for configuration changes
Evidence Format:
+
- Include validation logs, screenshots, or links to CI runs
- Provide clear, readable evidence
- Ensure evidence is recent and relevant
@@ -310,12 +330,14 @@
Test Data & Sample Inputs/Outputs
What Constitutes Good JSON Test Data?
- Validate against schema (if available)
- Include both valid and invalid examples
- Test for missing required fields, extra fields, and type mismatches
- Check for correct handling of comments (if allowed)
Example: Valid Config
{
"settingA": true,
@@ -324,17 +346,19 @@Example: Negative/Edge Case
{
- "settingA": "yes", // invalid type
- // missing maxItems
+ "settingA": "yes",
+ "maxItems": null
}Coverage Strategy
- For every config change, validate with schema and test both valid and invalid cases
- Document test data rationale in comments or PR description
\ No newline at end of file
Code of Conduct
-This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
+This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
diff --git a/.github/instructions/markdown.instructions.md b/.github/instructions/markdown.instructions.md
--- a/.github/instructions/markdown.instructions.md
+++ b/.github/instructions/markdown.instructions.md
@@ -12,12 +12,14 @@
Context Loading for Copilot
When working on this file type, you MUST:
+
- Read this entire instruction file before making any changes
- Cross-reference with related instruction files (listed below)
- Validate your understanding by checking the "Validation Checklist" section
- If uncertain about any requirement, stop and request clarification
Related Instruction Files:
+
- csharp.instructions.md - For C# code changes
- project.instructions.md - For build configuration changes
... diff truncated: showing 800 of 3991 lines
</details>
<!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_END -->
Pin actions/checkout and super-linter to commit SHAs for supply-chain security. Upgrade super-linter from v6.6.0 to v8.5.0. Enable only YAML, Markdown, JSON, Bash, and GitHub Actions linters (C# and PowerShell are already covered by dedicated workflows). Add yamllint and markdownlint configs. Exclude .verified.* test snapshot files. Document local linting instructions in CONTRIBUTING.md. Fix all pre-existing lint violations across the codebase: - YAML: indentation, trailing spaces, bracket spacing, missing newlines across 11 workflow and config files - Markdown: blanks around fences/lists/tables/headings, trailing newlines, table pipe alignment, list marker spacing, emphasis style, bare URLs across 26 documentation files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
247f185 to
8e42ccd
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces repository-wide linting via SuperLinter (with SHA pinning) and adds centralized linter configuration files, alongside broad documentation/instruction formatting updates and minor workflow/script adjustments.
Changes:
- Add SuperLinter workflow (pinned by commit SHA) and linter config files for Markdown/YAML.
- Update contributor documentation and instruction files to document/align local linting and formatting expectations.
- Misc workflow/script formatting + perf wrapper argument forwarding change.
Reviewed changes
Copilot reviewed 42 out of 54 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/linters.yml |
Adds SuperLinter CI workflow and config wiring. |
.yamllint.yml |
Adds shared yamllint configuration for CI/local runs. |
.markdownlint.json |
Adds shared markdownlint configuration for CI/local runs. |
actionlint.yml |
Configures actionlint to recognize the repo’s self-hosted runner label. |
CONTRIBUTING.md |
Documents local linting tool installation and local linting commands; formatting edits. |
docs/dependency-management.md |
Table formatting/markdown cleanup. |
docs/rules/README.md |
Table formatting/markdown cleanup for rule index + ID ranges. |
docs/rules/Moq1000.md |
Markdown formatting cleanup. |
docs/rules/Moq1001.md |
Markdown formatting cleanup. |
docs/rules/Moq1002.md |
Markdown formatting cleanup. |
docs/rules/Moq1100.md |
Markdown formatting cleanup. |
docs/rules/Moq1101.md |
Markdown formatting cleanup. |
docs/rules/Moq1200.md |
Markdown formatting cleanup. |
docs/rules/Moq1201.md |
Markdown formatting cleanup. |
docs/rules/Moq1202.md |
Markdown formatting cleanup. |
docs/rules/Moq1203.md |
Markdown formatting cleanup. |
docs/rules/Moq1204.md |
Markdown formatting cleanup. |
docs/rules/Moq1206.md |
Markdown formatting cleanup (table alignment + spacing). |
docs/rules/Moq1207.md |
Markdown formatting cleanup (table + spacing). |
docs/rules/Moq1210.md |
Markdown formatting cleanup. |
docs/rules/Moq1300.md |
Markdown formatting cleanup. |
docs/rules/Moq1301.md |
Markdown formatting cleanup. |
docs/rules/Moq1302.md |
Markdown formatting cleanup (adds spacing before list). |
docs/rules/Moq1400.md |
Markdown formatting cleanup. |
docs/rules/Moq1420.md |
Markdown formatting cleanup. |
docs/rules/Moq1500.md |
Markdown formatting cleanup. |
Perf.sh |
Updates perf wrapper invocation (argument forwarding behavior changed). |
build/scripts/perf/CIPerf.sh |
Updates CI perf wrapper invocation (argument forwarding behavior changed). |
.github/workflows/main.yml |
Workflow YAML formatting/quoting adjustments. |
.github/workflows/release.yml |
Trims trailing whitespace in publish step. |
.github/workflows/milestone-tracking.yml |
YAML + shell quoting tweaks; adds shellcheck suppression comment. |
.github/workflows/pr-labeler-current-milestone.yml |
YAML indentation/whitespace normalization. |
.github/workflows/powershell.yml |
YAML formatting normalization for branch arrays. |
.github/workflows/devskim.yml |
YAML formatting normalization for branch arrays. |
.github/workflows/label-pr.yml |
YAML indentation normalization. |
.github/workflows/label-issues.yml |
Whitespace normalization in inline JS. |
.github/workflows/copilot-setup-steps.yml |
Whitespace normalization. |
.github/labeler.yml |
YAML indentation normalization for label rules. |
.github/dependabot.yml |
Comment indentation normalization. |
.github/copilot-instructions.md |
Markdown table formatting + spacing cleanup. |
.github/instructions/README.md |
Markdown table reformatted to standard pipes. |
.github/instructions/csharp.instructions.md |
Markdown heading/code block indentation cleanup. |
.github/instructions/project.instructions.md |
Markdown heading/spacing cleanup. |
.github/instructions/markdown.instructions.md |
Markdown spacing/code fence annotation cleanup. |
.github/instructions/json.instructions.md |
Markdown spacing/code fence annotation cleanup + example JSON adjusted. |
.github/instructions/yaml.instructions.md |
Markdown spacing/code fence annotation cleanup. |
.github/instructions/xml.instructions.md |
Markdown spacing/code fence annotation cleanup. |
.github/instructions/text.instructions.md |
Markdown spacing/code fence annotation cleanup. |
.github/instructions/shell.instructions.md |
Markdown spacing/code fence annotation cleanup. |
.github/instructions/msbuild.instructions.md |
Markdown spacing cleanup. |
.github/instructions/generic.instructions.md |
Markdown spacing cleanup. |
.github/instructions/gitignore.instructions.md |
Markdown spacing cleanup. |
.github/instructions/editorconfig.instructions.md |
Markdown spacing cleanup. |
.codacy/cli.sh |
Refactors local assignments to satisfy shell linting rules. |
src/Analyzers/AnalyzerReleases.Unshipped.md |
Release tracking content present; verified table formatting remains Roslyn-friendly. |
src/Analyzers/AnalyzerReleases.Shipped.md |
Release tracking content present; verified table formatting remains Roslyn-friendly. |
Summary
Add super-linter v8.5.0 as a CI lint workflow to enforce consistent formatting across YAML, Markdown, JSON, Bash, and GitHub Actions files. Fix all pre-existing lint violations across the codebase so CI passes cleanly.
Changes
New files
.github/workflows/linters.yml- Super-linter workflow (SHA-pinned actions, least-privilege permissions).markdownlint.json- Markdownlint config (disables MD013, MD024, MD033, MD041).yamllint.yml- yamllint config (truthy key check disabled for Actionson:, line-length max 320)actionlint.yml- Registerswindows-2025-vs2026custom runner labelLint violation fixes (54 files)
$*to-File+"$@"), SC2155 (separate declare/assign), SC2086 (unquoted variables)run:blocks, unquoted shell variables, addedactionlint.ymlfor custom runnerDocumentation
CONTRIBUTING.md: Added local linting tools to "Getting Started" and "Local Linting" section with yamllint, markdownlint, and Docker commandsDesign decisions
actions/checkoutandsuper-linterpinned to commit SHAs with version comments for supply-chain security.verified.*test snapshots,AnalyzerReleases.*.md(Roslyn RS2007 parser requires specific table format), and tool config directories (.cursor/,.agents/, etc.)MARKDOWN_CONFIG_FILEandYAML_CONFIG_FILEenv vars because super-linter defaults differ from standard tool conventionsTest plan
Closes #94